﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using ASmile.Extend;

namespace ASmile.Event
{
    public static class EventTool
    {
        /// <summary>
        /// 订阅兑现列表
        /// </summary>
        public static List<IEventSubscribe> SubscribeList { get; } = new List<IEventSubscribe>();
        /// <summary>
        /// 取消订阅
        /// </summary>
        public static void SubscribeCancel(IEventSubscribe eventSubscribe)
        {
            SubscribeList.Remove(eventSubscribe);
        }
        /// <summary>
        /// 按Id取消订阅
        /// </summary>
        public static void SubscribeCancel(string eventId)
        {
            SubscribeList.Remove(s => s.ID == eventId);
        }
        /// <summary>
        /// 事件订阅
        /// </summary>
        public static bool Subscribe(IEventSubscribe regObj)
        {
            if (regObj == null)
            {
                LogHelper.LogObj.Info($"订阅对象为空，订阅失败");
                return false;
            }
            if (regObj.ID.IsEmpty())
            {
                LogHelper.LogObj.Info($"订阅ID空，订阅失败");
                return false;
            }
            if (SubscribeList.Contains(regObj))
            {
                LogHelper.LogObj.Info($"{regObj.GetType()} 已经存在，不允许重复添加");
                return false;
            }
            if (SubscribeList.Exists(s => s.ID == regObj.ID))
            {
                LogHelper.LogObj.Info($"{regObj.GetType()} 已经ID({regObj.ID})存在，不允许重复添加");
                return false;
            }
            if (regObj is IEventFormSubscribe formSubscribe)
            {
                formSubscribe.Disposed += FormSubscribe_Disposed;
            }
            SubscribeList.Add(regObj);
            return true;
        }

        private static void FormSubscribe_Disposed(object sender, EventArgs e)
        {
            if (sender is IEventSubscribe subscribe)
            {
                SubscribeList.Remove(s => s.ID == subscribe.ID);
            }
        }

        static TriggerResult RunTriggerTask(object state)
        {
            var eArg = state as TriggerArg;

            var subList = SubscribeList.FindAll(s => s.EventName == eArg.EventName);
            if (subList.Count == 0)
            {
                return new TriggerResult(-1, $"{eArg.EventName} 订阅者列表为空");
            }
            TriggerResult result = null;
            TriggerResult resultLast = null;
            List<string> invalidSubscribe = new List<string>();
            var a = subList.OrderByDescending(s => s.OrderNo);
            foreach (var item in a)
            {
                if (item == null)
                {
                    invalidSubscribe.Add(item.ID);
                    continue;
                }

                if (item.IsDisposed)
                {
                    continue;
                }
                //if (item is IEventFormSubscribe form && form.IsDisposed)
                //{
                //    invalidSubscribe.Add(item.ID);
                //    continue;
                //}
                try
                {
                    //本次结果
                    resultLast = item.Execute(eArg);
                    if (resultLast == null || !resultLast.Success)
                    {
                        continue;
                    }
                    resultLast.Subscribe = item;
                    resultLast.LastResult = result;

                    if (result == null)
                    {
                        result = new TriggerResult();
                    }
                    result.Values.SetObject(resultLast.Values);
                    result.LastResult = resultLast;
                    result.Tag = resultLast.Tag;
                    eArg.LastResult = resultLast;

                    if (resultLast.IsBreak)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.LogObj.Error($"执行 {item.EventName}({item.EventCaption}) 时异常", ex);
                }
            }
            SubscribeList.Remove(s => s.IsDisposed == true);
            return result ?? resultLast;
        }

        /// <summary>
        /// 触发事件
        /// </summary>
        public static Task<TriggerResult> Trigger(TriggerArg arg)
        {
            Task<TriggerResult> task = new Task<TriggerResult>(RunTriggerTask, arg);
            task.Start();
            return task;
        }
        /// <summary>
        /// 简单触发，指定事件名及字典参数
        /// </summary>
        public static Task<TriggerResult> Trigger(string eventName, DictExtend arg = null)
        {
            TriggerArg a = new TriggerArg
            {
                EventName = eventName,
            };
            a.Values.SetObject(arg);
            return Trigger(a);
        }
        /// <summary>
        /// 同步执行，非线程，该操作会阻塞整个事件任务
        /// </summary>
        public static TriggerResult TriggerSync(TriggerArg arg)
        {
            return RunTriggerTask(arg);
        }
        /// <summary>
        /// 同步执行，非线程，该操作会阻塞整个事件任务
        /// </summary>
        public static TriggerResult TriggerSync(string eventName, DictExtend arg = null)
        {
            TriggerArg a = new TriggerArg
            {
                EventName = eventName,
            };
            a.Values.SetObject(arg);
            return TriggerSync(a);
        }
    }
}